import gtk,gobject
import Locations
import Shares
import PreferencesWindow
import RegexEditor

class UIManager(gtk.UIManager):
    '''UIManager manage all user interface like menubar/toolbar/trayicon'''
    
    def __init__(self,controller):
        '''constructor'''
        
        gtk.UIManager.__init__(self)
        
        self.controller = controller
        self.accel_group = self.get_accel_group()
        
        #Menubar
        menubar_action_group = gtk.ActionGroup('menubar_action_group')
        menubar_action_group.add_actions([('file',None,'_File'),
                                            ('import',gtk.STOCK_GOTO_FIRST,'_Import',None,'Import a miam file',self.import_callback),
                                            ('export',gtk.STOCK_GOTO_LAST,'_Export',None,'Export a miam file',self.export_callback),
                                            ('exit',gtk.STOCK_QUIT,'_Exit',None,'Exit Miam',self.exit_callback),
                                          ('edit',None,'_Edit'),
                                            ('add location',gtk.STOCK_ADD,'_Add Location',None,'Add a location',self.add_location_callback),
                                          ('actions',None,'_Actions'),
                                            ('mount',None,'_Mount',None,'mount a share',self.mount_callback),
                                            ('unmount',None,'_Unmount',None,'unmount a share',self.unmount_callback),
                                            ('unmount all',None,'_Unmount all',None,'unmount all shares',self.unmount_all_callback),
                                          ('tools',None,'_Tools'),
                                            ('regex editor',None,'_Regex Editor',None,'Regex Editor',self.regex_editor_callback),
                                            ('preferences',gtk.STOCK_PREFERENCES,'_Preferences',None,'Set preferences',self.preferences_callback),
                                            ('test',None,'_test',None,'Test',self.controller.test)
                                          ])
        self.insert_action_group(menubar_action_group,0)
        
        #Toolbar
        toolbar_action_group = gtk.ActionGroup('toolbar_action_group')
        toolbar_action_group.add_actions([('add location',gtk.STOCK_ADD,'_Add Location',None,'Add a location',self.add_location_callback), #useless c l'autre qui est utilise (ajoute en 1er)
                                          ('add share',gtk.STOCK_ADD,'_Add Share',None,'Add a share',self.add_share_callback),
                                          ('edit item',gtk.STOCK_EDIT,'_Edit Item',None,'Edit Item',self.edit_item_callback),
                                          ('remove item',gtk.STOCK_DELETE,'_Remove Item',None,'Remove Item',self.remove_item_callback),
                                          ('mount',gtk.STOCK_HARDDISK,'_Mount Share',None,'Mount a share',self.mount_callback),
                                          ('unmount',gtk.STOCK_HARDDISK,'_Unmount Share',None,'Unmount a share',self.unmount_callback),
                                          ])
        self.insert_action_group(toolbar_action_group,0)
        
        self.add_ui_from_file('ui.xml')
        
    # UImanager Callbacks
    def import_callback(self, widget=None):
        self.controller.xml_import()
    
    def export_callback(self, widget=None):
        self.controller.xml_export()
    
    def regex_editor_callback(self, widget=None):
        RegexEditor.RegexEditor(self.controller)
    
    def preferences_callback(self, widget=None):
        PreferencesWindow.PreferencesWindow(self.controller)
        
    def add_location_callback(self, widget=None):
        self.controller.add_location()
    
    def add_share_callback(self, widget=None):
        self.controller.add_share()
    
    def edit_item_callback(self, widget=None):
        item = self.controller.main_window.get_item_by_cursor()
        if isinstance(item,Locations.Location):
            if item.id: # You Can't edit the Everywhere location (id = 0)
                self.controller.edit_location(item)
        elif isinstance(item,Shares.Share):
            self.controller.edit_share(item)
    
    def remove_item_callback(self, widger=None):
        item = self.controller.main_window.get_item_by_cursor()
        if isinstance(item,Locations.Location):
            if item.id: # You Can't delete the Everywhere location (id = 0)
                self.controller.remove_location(item)
        elif isinstance(item,Shares.Share):
            self.controller.remove_share(item)
        
    def mount_callback(self,widget=None):
        item = self.controller.main_window.get_item_by_cursor()
        if isinstance(item,Shares.Share):
            self.controller.mount_share(item)
    
    def unmount_callback(self,widget=None):
        item = self.controller.main_window.get_item_by_cursor()
        if isinstance(item,Shares.Share):
            self.controller.unmount_share(item)
    
    def unmount_all_callback(self,widget=None):
        self.controller.unmount_all()
    
    def exit_callback(self,widget=None):
        self.controller.exit()      

class TrayIcon(gtk.StatusIcon):
    '''This is the MIAM trayicon'''
    def __init__(self,controller):
        '''constructor'''
        gtk.StatusIcon.__init__(self)
        self.controller = controller
        self.notif_window = None
        self.close_notif_src = None
        self.set_from_file(self.controller.config.path['IMAGES']+'ico.png') # Icon, will be replace soon by a pixbuff with the miam logo
        self.connect("activate",self.trayicon_activate_callback)
        self.connect("popup-menu",self.trayicon_popup_menu_callback)
        self.controller.shares.connect("set::mount",self.share_mounted_callback)
        self.controller.shares.connect("set::unmount",self.share_unmounted_callback)
        self.set_visible(True)
    
    def build_menu_item(self,label,callback=None,share=None):
        item = gtk.MenuItem(label)
        if callback:
            if share:
                item.connect("activate",callback,share)
            else:
                item.connect("activate",callback)
        return item
    
    def build_traymenu(self):
        menu = gtk.Menu()
    
        menu.append(self.build_menu_item('automount',self.automount_callback))
        
        if self.controller.config.network['CURRENT LOCATION']:
            menu.append(gtk.SeparatorMenuItem())
            
            mount_sub_menu = self.build_mount_submenu(self.mount_callback)
            if mount_sub_menu :
                mount_menu = self.build_menu_item('mount')
                mount_menu.set_submenu(mount_sub_menu)
                menu.append(mount_menu)
            
            open_sub_menu = self.build_open_submenu(self.show_callback)
            if open_sub_menu:
                open_menu = self.build_menu_item('open')
                open_menu.set_submenu(open_sub_menu)
                menu.append(open_menu)
            
            umount_sub_menu = self.build_umount_submenu(self.unmount_callback)
            if umount_sub_menu:
                unmount_menu = self.build_menu_item('unmount')
                unmount_menu.set_submenu(umount_sub_menu)
                menu.append(unmount_menu)
            
            if mount_sub_menu or open_sub_menu or umount_sub_menu:
                menu.append(gtk.SeparatorMenuItem())
        
        menu.append(self.build_menu_item('exit',self.exit_callback))
        
        menu.show_all()
        
        self.traymenu = menu
    
    def build_open_submenu(self,callback):
        open_menu = gtk.Menu()
        
        everywhere_mounted_shares = [shares for shares in self.controller.shares.get_shares_by_location(self.controller.locations[0]) if shares.mounted]
        currloc_mounted_shares = [shares for shares in self.controller.shares.get_shares_by_location(self.controller.config.network['CURRENT LOCATION']) if shares.mounted]
                    
        if len(everywhere_mounted_shares):
            for share in everywhere_mounted_shares: 
                open_menu.append(self.build_menu_item(share.name, callback,share))
        
        if self.controller.config.network['CURRENT LOCATION'].id != 0:
            if len(everywhere_mounted_shares) and len(currloc_mounted_shares):
                open_menu.append(gtk.SeparatorMenuItem())
            for share in currloc_mounted_shares:
                open_menu.append(self.build_menu_item(share.name, callback,share))
        
        if len(everywhere_mounted_shares) or len(currloc_mounted_shares):
            return open_menu
    
    def build_mount_submenu(self,callback):
        mount_menu = gtk.Menu()
        everywhere_shares = [shares for shares in self.controller.shares.get_shares_by_location(self.controller.locations[0]) if not shares.mounted]
        currloc_shares = [shares for shares in self.controller.shares.get_shares_by_location(self.controller.config.network['CURRENT LOCATION']) if not shares.mounted]
        
        if len(everywhere_shares):
            for share in everywhere_shares :            
                mount_menu.append(self.build_menu_item(share.name, callback,share))
        
        if self.controller.config.network['CURRENT LOCATION'].id != 0:
            if len(everywhere_shares) and len(currloc_shares):
                mount_menu.append(gtk.SeparatorMenuItem())
            for share in currloc_shares :
                mount_menu.append(self.build_menu_item(share.name, callback,share))
        
        if len(everywhere_shares) or len(currloc_shares):
            return mount_menu
    
    def build_umount_submenu(self,callback):
        umount_menu = gtk.Menu()
        
        mounted_shares = self.controller.mtab.mounted_shares
        for share in mounted_shares:
            umount_menu.append(self.build_menu_item(share.name, callback,share))
        
        if len(mounted_shares):
            return umount_menu
        
        
    def notif(self,message):
        if self.notif_window:
            self.close_notif()
            
        self.notif_window = gtk.Window(type=gtk.WINDOW_POPUP)
        label = gtk.Label(message)
        label.set_size_request(label.size_request()[0] , label.size_request()[1]+10)
        eventbox = gtk.EventBox()
        eventbox.set_events (gtk.gdk.BUTTON_PRESS_MASK)
        eventbox.connect("button-press-event",self.close_notif)
        eventbox.add(label)
        self.notif_window.add(eventbox)
        
        rect = self.get_geometry()[1]
        self.notif_window.move(rect.x,abs(rect.y-(self.get_size()+5)))
        
        self.close_notif_src = gobject.timeout_add(3000,self.close_notif)
        
        self.notif_window.show_all()

        size = self.notif_window.get_size()
        self.notif_window.resize(size[0]+10,size[1])
        
    #Callbacks
    def close_notif(self,*args):
        if self.close_notif_src:
            gobject.source_remove(self.close_notif_src)
            close_notif_src = None
            
        if self.notif_window:
            self.notif_window.destroy()
            self.notif_window = None
    
    def get_menu_position(self,menu):
        rect = self.get_geometry()[1]
        x = rect.x
        y = rect.y + self.get_size()
        return x,y,False
      
    def automount_callback(self,widget=None):
        print "Not implemented Yet"
    
    def mount_callback(self,widget,share):
        self.controller.mount_share(share)
    
    def show_callback(self,widget,share):
        self.controller.open_share(share)
    
    def unmount_callback(self,widget,share):
        self.controller.unmount_share(share)
    
    def unmount_all_callback(self,widget,share):
        self.controller.unmount_all()
    
    def exit_callback(self,widget):
        self.controller.exit()  
    
    def trayicon_activate_callback(self,widget=None):
        '''call when a right click occurs on the trayicon,show/hide windows'''
        if self.controller.main_window in gtk.window_list_toplevels():
            self.controller.hide()
        else:
            self.controller.show()
                                
    def trayicon_popup_menu_callback(self,widget,button,time):
        '''call when a left click occurs on the trayicon, popup the tray menu'''
        self.build_traymenu()
        self.traymenu.popup(None,None,self.get_menu_position,button,time)
        
    def share_mounted_callback(self,widget,share):
        msg = share.name + " is now mounted on\n" + self.controller.mtab.mounted_shares[share]
        self.notif(msg)
        
    def share_unmounted_callback(self,widget,share):
        msg = share.name + " has been unmounted"
        self.notif(msg)
